﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Clock.Utils;

namespace Clock.ImageProcessing
{
    public enum ContentDetection { Cautious, Normal, Aggressive }
    public enum Orientation { Left , Right , UpsideDown , None }
    public enum Layout { Auto = 0, OnePage = 1, OnePageCuttingNeeded = 4, TwoPage = 2 }
    public enum ColorMode { Black_And_White, Color_Grayscale , Mixed  }
    public enum DespeckleMode { Cautious = 0, Normal = 1, Aggressive = 2, Off=3  }
    public class ScanTailor : OsUtil
    {
        IList<string> Options { get; set; }
        public bool Deskew { get; set; }
        public bool Dewarp { get; set; }
        /// <summary>
        /// output DPI
        /// </summary>
        public int Dpi { get; set; }
        /// <summary>
        /// Rotate 0 to 360
        /// </summary>
        public int Rotate { get; set; }
        public int Threshold { get; set; }
        
        public ContentDetection ContentDetection { get; set; }
        public Orientation Orientation { get; set; }
        public Layout Layout { get; set; }
        public ColorMode ColorMode { get; set; }
        public DespeckleMode Despeckle { get; set; }
        public int MarginLeft { get; set; }
        public int MarginRight { get; set; }
        public int MarginTop { get; set; }
        public int MarginBottom { get; set; }
        string Command = GetProgramPath("Scan Tailor", "scantailor-cli.exe");
        public string OutputDirectory { get; set; }
        public bool ScanTailorExist
        {
            get
            {
                return File.Exists(Command);
            }
        }

        public ScanTailor()
        {
            OutputDirectory = TempData.Instance.CurrentJobFolder;
            Deskew = true;
            Dewarp = false;
            ContentDetection = Clock.ImageProcessing.ContentDetection.Normal;
            ColorMode = Clock.ImageProcessing.ColorMode.Black_And_White;
            Layout = Clock.ImageProcessing.Layout.Auto;
            Orientation = Clock.ImageProcessing.Orientation.None;
            Threshold = 0;
            Dpi = 600;
            Rotate = 0;
            Options = new List<string>();
        }

        public string ProcessImage(string Image)
        {
            string options = GetOptionsCommandLine();


            string Arguments = string.Concat(" ", options, "\"", Image, "\"", " ", "\"", OutputDirectory, "\"");
            ProcessCommand(Command, Arguments);
            return Path.Combine(OutputDirectory, Path.GetFileNameWithoutExtension(Image) + ".tif");
        }

        private string GetOptionsCommandLine()
        {
            Options = new List<string>();
            Options.Add("--layout=" + (Layout == ImageProcessing.Layout.OnePageCuttingNeeded ? "1.5" : ((int)Layout).ToString()));
            if(Orientation != ImageProcessing.Orientation.None)
                Options.Add("--orientation=" + Enum.GetName(typeof(Orientation), Orientation).ToLower());
            Options.Add("--deskew=" + (Deskew ? "auto" : "manual"));
            Options.Add("--content-detection=" + Enum.GetName(typeof(ContentDetection),ContentDetection).ToLower());
            Options.Add("--margin-left=" + MarginLeft.ToString());
            Options.Add("--margin-right=" + MarginRight.ToString());
            Options.Add("--margin-top=" + MarginTop.ToString());
            Options.Add("--margin-bottom=" + MarginBottom.ToString());

            
            if(Rotate > 0)
                Options.Add("--rotate=" + Rotate.ToString());

            Options.Add("--output-dpi=" + Dpi.ToString());
            Options.Add("--color-mode=" + Enum.GetName(typeof(ColorMode), ColorMode).ToLower());
            Options.Add("--threshold=" + Threshold.ToString());
            Options.Add("--despeckle=" + Enum.GetName(typeof(DespeckleMode), Despeckle).ToLower());
            Options.Add("--dewarping=" + (Dewarp ? "auto" : "off"));
            string commandLineOptions = "";
            foreach (string o in Options)
            {
                commandLineOptions += o + " ";
            }
            return commandLineOptions;
        }
    }
}
